package dbsync4j.mapper.concrete.compare;

import java.util.Collection;
import java.util.Map;

import dbsync4j.core.behavior.DatabaseObject;
import dbsync4j.core.behavior.ForeignKey;
import dbsync4j.core.behavior.ForeignKeyMapping;
import dbsync4j.mapper.behavior.compare.DifferenceCompare;
import dbsync4j.mapper.behavior.diff.Difference;
import dbsync4j.mapper.concrete.diff.AttributeValueDifference;
import dbsync4j.mapper.concrete.diff.NullPointerDifference;

public class ConcreteForeingKeyDifferenceCompare extends AbstractDifferenceCompare
implements DifferenceCompare {

	public ConcreteForeingKeyDifferenceCompare(DatabaseObject sourceForeignKey, DatabaseObject destinyForeignKey) {

		super(sourceForeignKey, destinyForeignKey);
	}

	/* (non-Javadoc)
	 * @see dbsync4j.mapper.behavior.compare.DifferenceCompare#diff()
	 */
	@Override
	public Collection<Difference> diff() {

		String tag = null;
		ForeignKey fkSource = (ForeignKey) this.source;
		ForeignKey fkDestiny = (ForeignKey) this.destiny;

		/* verifica se a lista de diferen�as j� possui ao menos um item */
		if(differences.size() == 0 ) { 
			if(this.source == null && this.destiny == null) {

				return differences;

			} else if(this.source == null || this.destiny == null) {

				tag = "foreignkeypair";
				differences.add(new NullPointerDifference(source, destiny, tag));

			} else {

				tag = "foreignkeyattribute";
				Map<String, String> diffResult = compareObjects(tag, source, destiny);
				Collection<String> diffKeys = diffResult.keySet();

				for(String d : diffKeys) {
					String attribute = d.replace(tag.concat("."), "");
					differences.add(new AttributeValueDifference(this.source, this.destiny, attribute, tag));
				}

				
				tag = "foreignkeycolumnpair";
				ForeignKey fkx = null;
				ForeignKey fky = null;
				boolean aux = true;

				for(int i = 1 ; i <= 2; i++) {

					fkx = (aux) ? fkSource : fkDestiny;
					fky = (!aux) ? fkSource : fkDestiny;

					Collection<ForeignKeyMapping> sForeignKeyMapping = fkx.getForeignKeyMapping();

					for(ForeignKeyMapping sFkm : sForeignKeyMapping) {

						ForeignKeyMapping foreignKeyColumnMap = fky.getForeignKeyColumnMap(sFkm.getForeignKeyColumn().getName());
						ForeignKeyMapping primaryKeyColumnMap = fky.getPrimaryKeyColumnMap(sFkm.getPrimaryKeyColumn().getName());

						if(foreignKeyColumnMap == null) {

							if(aux) {
								differences.add(new NullPointerDifference(sFkm.getForeignKeyColumn(), null, tag));
							} else {
								differences.add(new NullPointerDifference(null, sFkm.getForeignKeyColumn(), tag));
							}
						}

						if(primaryKeyColumnMap == null) {

							if(aux) {
								differences.add(new NullPointerDifference(sFkm.getPrimaryKeyColumn(), null, tag));
							} else {
								differences.add(new NullPointerDifference(null, sFkm.getPrimaryKeyColumn(), tag));
							}
						}

					}

					aux = !aux;
				}
			} 
		}

		return differences;
	}

}
